package com.example.replacebooks.common;

import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.example.replacebooks.entity.User;
import com.example.replacebooks.exception.CustomException;
import com.example.replacebooks.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/* jwt 拦截器 */
@Component
public class JwtInterceptor implements HandlerInterceptor {
    private static final Logger log = LoggerFactory.getLogger(JwtInterceptor.class);

    @Resource
    private UserService userService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler){
        // 1. 从http请求的header中获取token
        String token = request.getHeader("token");
        if (StrUtil.isBlank(token)){
            // 如果没拿到，再去参数里面拿一波试试
            token = request.getParameter("token");
        }
        // 2. 开始执行认证
        if (StrUtil.isBlank(token)){
            throw new CustomException("无token,请重新登录");
        }
        // 获取 token 中的 username
        String userid;
        User user;
        try{
            // decode 将 token 解码，得到 userid
            userid = JWT.decode(token).getAudience().get(0);
            // 根据 token 中的 userid 查询数据库
            user = userService.findById(Integer.parseInt(userid));
        }catch (Exception e){
            String errMsg = "token 验证失败，请重新登录";
            log.error(errMsg + ", token = "+token ,e);
            throw new CustomException(errMsg);
        }
        if (user == null){
            throw new CustomException("用户不存在，请重新登录");
        }
        try{
            //用户密码加验证 token
            JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();
            jwtVerifier.verify(token); //验证token
        }catch (JWTVerificationException e){
            throw new CustomException("token 验证失败，请重新登录");
        }
        return true;
    }
}
